home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1993, 1994 Marc Parmet.
- * This file is part of the Macintosh port of GNU Emacs.
- *
- * GNU Emacs is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
- #if defined(THINK_C)
- #include <MacHeaders>
- #else
- #include <Types.h>
- #include <Memory.h>
- #include <Quickdraw.h>
- #include <Windows.h>
- #include <Resources.h>
- #endif
-
- #include "stdio.h"
- #include "config.h"
- #include "lisp.h"
- #include "buffer.h"
-
- #if defined(THINKC)
- /* Pull out all the stops. */
- #pragma options(global_optimizer,gopt_induction,gopt_cse,gopt_loop,gopt_coloring)
- #endif
-
- #define lisp_objects_in_buffer ((sizeof(struct buffer) - \
- ((int)&((struct buffer *)0)->name)) / sizeof(int))
-
- /* From ealloc.c */
- extern char *pure;
- extern int staticidx;
- extern char staticvec1[];
- #define staticvec ((Lisp_Object **) staticvec1)
-
- /* These things are not protected with staticpro, not declared with DEFVAR_BOOL
- or DEFVAR_INT, but we need to save and restore anyway. */
- extern struct buffer *current_buffer,*all_buffers;
- extern Lisp_Object selected_window;
- extern Lisp_Object global_map;
- extern Lisp_Object Qvariable_documentation;
- extern int unrch;
-
- struct globals_to_save {
- int *address;
- char untagged,tag;
- } globals_to_save[] = {
- { (int *)¤t_buffer, 1, Lisp_Buffer, },
- { (int *)&all_buffers, 1, Lisp_Buffer, },
- { (int *)&selected_window, 0, },
- { (int *)&global_map, 0, },
- { (int *)&Qvariable_documentation, 0, },
- { (int *)&unrch, 1, Lisp_Int, },
- };
- #define nglobals_to_save (sizeof(globals_to_save) / sizeof(struct globals_to_save))
-
- /* These three buffers are kept in static memory. The first two also
- have statically protected pointers pointing to them. When we restore these
- first two buffers, we must therefore restore them back into their static areas.
- The third buffer is not statically protected, but here we can simply save and
- restore its contents -- it contains no pointers. */
- extern struct buffer buffer_defaults,buffer_local_symbols,buffer_local_flags;
-
- #define DUMP_VECTOR_MAX 130000
- static char *dump_vector;
- static int dump_free;
- static struct dumped_address_and_object {
- Lisp_Object object;
- int address;
- } *dumped_staticvec;
-
- /* Offsets we store can be relative to three different bases, or can be absolute. */
- #define NO_SEGMENT 0
- #define DATA_SEGMENT 1
- #define PURE_SEGMENT 2
- #define DUMP_SEGMENT 3
-
- #define SEGMENTBITS 2 /* We have four different segments, thus two bits. */
- #define OFFSETBITS (VALBITS - SEGMENTBITS)
- #define NONOFFSETBITS (32 - OFFSETBITS)
-
- #define OFFSET_MASK ((1 << OFFSETBITS) - 1)
- #define SEGMENT(X) ((X >> OFFSETBITS) & ((1<<SEGMENTBITS)-1))
- #undef OFFSET /* Defined in asm.h originally, delivered here by MacHeaders */
- #define OFFSET(X) ((X << NONOFFSETBITS) >> NONOFFSETBITS)
- #define DATA_SEGMENT_MASK (DATA_SEGMENT << OFFSETBITS)
- #define PURE_SEGMENT_MASK (PURE_SEGMENT << OFFSETBITS)
- #define DUMP_SEGMENT_MASK (DUMP_SEGMENT << OFFSETBITS)
- #define OFFSET_IN_DATA(X) \
- (((XPNTR((int)X) - (int)&pure) & OFFSET_MASK) | DATA_SEGMENT_MASK)
- #define OFFSET_IN_PURE(X) \
- (((XPNTR((int)X) - (int)pure) & OFFSET_MASK) | PURE_SEGMENT_MASK)
- #define OFFSET_IN_DUMP(X) \
- (((XPNTR((int)X) - (int)dump_vector) & OFFSET_MASK) | DUMP_SEGMENT_MASK)
-
- /* Just for fun */
- int total_fixups;
-
- #if defined(powerc)
- #define DUMP_RSRC_BASE 131
- #else
- #define DUMP_RSRC_BASE 128
- #endif
-
- #define STATICVEC_DUMP DUMP_RSRC_BASE
- #define IMPURE_DUMP (DUMP_RSRC_BASE+1)
- #define PURE_DUMP (DUMP_RSRC_BASE+2)
-
- static void
- panic(char *s)
- {
- EventRecord e;
-
- printf("\012%s\012",s);
- fflush(stdout);
- while (!WaitNextEvent(mDownMask,&e,10,0))
- ;
- ExitToShell();
- }
-
- static int
- in_pure_space(Lisp_Object p)
- {
- p = XPNTR(p);
- return p < (int)pure + PURESIZE && p >= (int)pure;
- }
-
- static void *
- dump_alloc(int n)
- {
- char *c;
-
- if (dump_free+n >= DUMP_VECTOR_MAX)
- panic("dump vector overflow -- "
- "need to recompile Emacs with a larger dump vector");
- c = dump_vector + dump_free;
- dump_free += n;
- return c;
- }
-
- static void
- spin_chores(void)
- {
- int time;
- static int last_spin_time;
-
- time = TickCount();
- if (time != last_spin_time && (time & 15) == 0) {
- last_spin_time = time;
- spin_beachball();
- }
- }
-
- static Lisp_Object dump_one_object(Lisp_Object);
- static Lisp_Object restore_one_object(Lisp_Object);
-
- static Lisp_Object
- dump_Lisp_String(Lisp_Object p)
- {
- char *s;
- int bytes,longwords,new;
-
- bytes = XSTRING(p)->size;
- if (XMARKBIT(bytes)) return XUNMARK(bytes);
-
- longwords = ((sizeof(int) + bytes + 1) - 1) / 4 + 1;
- s = dump_alloc(longwords * sizeof(int));
- XSET(new,Lisp_String,OFFSET_IN_DUMP(s));
- XSTRING(p)->size = new;
- XMARK(XSTRING(p)->size);
- *(int *)s = bytes;
- memcpy(s+sizeof(int),XSTRING(p)->data,bytes);
- return new;
- }
-
- static Lisp_Object
- restore_Lisp_String(int *a)
- {
- Lisp_Object t = a[0];
- if (XMARKBIT(t)) return XUNMARK(t);
- a[0] = t = make_string((char *)(a+1),*a);
- XMARK(a[0]);
- return t;
- }
-
- static Lisp_Object
- dump_Lisp_Vector(Lisp_Object p)
- {
- int *vector;
- int i,new,len = XVECTOR(p)->size;
-
- if (XMARKBIT(len)) return XUNMARK(len);
-
- vector = dump_alloc((len+1) * sizeof(int));
- XSET(new,XTYPE(p),OFFSET_IN_DUMP(vector));
- XVECTOR(p)->size = new;
- XMARK(XVECTOR(p)->size);
- vector[0] = len;
- for (i = 0; i<len; i++)
- vector[i+1] = dump_one_object(XVECTOR(p)->contents[i]);
- return new;
- }
-
- static Lisp_Object
- restore_Lisp_Vector(int *a,int type)
- {
- int *v,i,len,t;
- len = a[0];
- if (XMARKBIT(len)) return XUNMARK(len);
- a[0] = XSET(t,type,Fmake_vector(len,0));
- XMARK(a[0]);
- v = &XVECTOR(t)->contents[0];
- for (i = 0; i<len; ++i)
- v[i] = restore_one_object(a[i+1]);
- return t;
- }
-
- static Lisp_Object
- dump_Lisp_Symbol(Lisp_Object p)
- {
- int *symbol,plist,t,new;
-
- plist = XSYMBOL(p)->plist;
- if (XMARKBIT(plist)) return XUNMARK(plist);
-
- symbol = dump_alloc(5*sizeof(int));
- XSET(new,Lisp_Symbol,OFFSET_IN_DUMP(symbol));
- XSYMBOL(p)->plist = new;
- XMARK(XSYMBOL(p)->plist);
-
- symbol[0] = dump_one_object(XSET(t,Lisp_String,XSYMBOL(p)->name));
- symbol[1] = dump_one_object(XSYMBOL(p)->value);
- symbol[2] = dump_one_object(XSYMBOL(p)->function);
- symbol[3] = dump_one_object(plist);
- if (XSYMBOL(p)->next != 0L)
- symbol[4] = dump_one_object(XSET(t,Lisp_Symbol,XSYMBOL(p)->next));
- else
- symbol[4] = 0L;
- return new;
- }
-
- static Lisp_Object
- restore_Lisp_Symbol(int *a)
- {
- int plist,name,t;
- struct Lisp_Symbol *s;
-
- plist = a[3];
- if (XMARKBIT(plist)) return XUNMARK(plist);
- name = restore_one_object(a[0]);
- a[3] = t = Fmake_symbol(name);
- XMARK(a[3]);
- s = XSYMBOL(t);
- s->value = restore_one_object(a[1]);
- s->function = restore_one_object(a[2]);
- s->plist = restore_one_object(plist);
- s->next = (a[4] == 0L ? 0L : XSYMBOL(restore_one_object(a[4])));
- return t;
- }
-
- static Lisp_Object
- dump_Lisp_Subr(Lisp_Object p)
- {
- int new,*t = dump_alloc(2*sizeof(long));
- char *doc = XSUBR(p)->doc;
- XSET(t[0],XTYPE(p),OFFSET_IN_DATA(p));
- if ((int)doc <= 0)
- t[1] = (int)doc; /* Minus an offset into doc file. */
- else
- XSET(t[1],Lisp_Objfwd,OFFSET_IN_DATA(doc)); /* The address of a C string */
- return XSET(new,Lisp_Subr,OFFSET_IN_DUMP(t));
- }
-
- static Lisp_Object
- restore_Lisp_Subr(int *a)
- {
- int subr = restore_one_object(a[0]);
- int doc = a[1];
- if (doc <= 0)
- XSUBR(subr)->doc = (char *)doc; /* The offset into the DOC file */
- else
- XSUBR(subr)->doc = (char *)XPNTR(restore_one_object(doc)); /* In data area */
- return subr;
- }
-
- static Lisp_Object
- dump_Lisp_Cons(Lisp_Object p)
- {
- int *cons,car,new;
-
- car = XCONS(p)->car;
- if (XMARKBIT(car)) return XUNMARK(car);
- cons = dump_alloc(2*sizeof(Lisp_Object));
- XSET(new,XTYPE(p),OFFSET_IN_DUMP(cons));
- XCONS(p)->car = new;
- XMARK(XCONS(p)->car);
- cons[0] = dump_one_object(car);
- cons[1] = dump_one_object(XCONS(p)->cdr);
- return new;
- }
-
- static Lisp_Object
- restore_Lisp_Cons(int *a,int type)
- {
- int t,car = a[0];
- if (XMARKBIT(car)) return XUNMARK(car);
- a[0] = XSET(t,type,Fcons());
- XMARK(a[0]);
- XCONS(t)->car = restore_one_object(car);
- XCONS(t)->cdr = restore_one_object(a[1]);
- return t;
- }
-
- static Lisp_Object
- dump_Lisp_Buffer(Lisp_Object p)
- {
- int new,i,t,name;
- struct buffer *buffer;
-
- name = XBUFFER(p)->name;
- if (XMARKBIT(name)) return XUNMARK(name);
-
- buffer = dump_alloc(sizeof(int) + sizeof(struct buffer));
- XSET(new, Lisp_Buffer, OFFSET_IN_DUMP(buffer));
- XBUFFER(p)->name = new;
- XMARK(XBUFFER(p)->name);
-
- if (XBUFFER(p) == &buffer_defaults)
- *(int *)(buffer+1) = XSET(t,Lisp_Buffer,OFFSET_IN_DATA(&buffer_defaults));
- else if (XBUFFER(p) == &buffer_local_symbols)
- *(int *)(buffer+1) = XSET(t,Lisp_Buffer,OFFSET_IN_DATA(&buffer_local_symbols));
- else
- *(int *)(buffer+1) = 0;
-
- /* We will reinitialize text.beg when reloading. */
- *buffer = *XBUFFER(p);
-
- if (XBUFFER(p)->next != 0L)
- buffer->next = (struct buffer *)dump_one_object(XSET(t,Lisp_Buffer,XBUFFER(p)->next));
- else
- buffer->next = 0L;
-
- buffer->markers = dump_one_object(XBUFFER(p)->markers);
- buffer->name = dump_one_object(name);
- for (i = 1; i<lisp_objects_in_buffer; ++i)
- (&buffer->name)[i] = dump_one_object((&XBUFFER(p)->name)[i]);
- return new;
- }
-
- static Lisp_Object
- restore_Lisp_Buffer(int *a)
- {
- int buffer_offset,i,t;
- struct buffer *buffer_dst;
- struct buffer *buffer_src;
- int name;
-
- buffer_src = (struct buffer *)a;
- name = buffer_src->name;
- if (XMARKBIT(name)) return XUNMARK(name);
-
- buffer_offset = *(int *)(buffer_src+1);
- if (buffer_offset != 0L)
- buffer_dst = XBUFFER(restore_one_object(buffer_offset));
- else
- buffer_dst = (struct buffer *)malloc(sizeof(struct buffer));
-
- buffer_src->name = XSET(t,Lisp_Buffer,buffer_dst);
- XMARK(buffer_src->name);
-
- *buffer_dst = *buffer_src;
- buffer_dst->text.beg = (unsigned char *)malloc(50); /* How do we make sure this is enough? */
- if (buffer_src->next != 0L)
- buffer_dst->next = XBUFFER(restore_one_object((int)buffer_src->next));
- buffer_dst->markers = restore_one_object(buffer_src->markers);
- buffer_dst->name = restore_one_object(name);
- for (i = 1; i<lisp_objects_in_buffer; ++i)
- (&buffer_dst->name)[i] = restore_one_object((&buffer_src->name)[i]);
- return t;
- }
-
- static Lisp_Object
- dump_Lisp_Marker(Lisp_Object p)
- {
- int chain,t,new,*marker;
- struct buffer *buffer;
-
- chain = XMARKER(p)->chain;
- if (XMARKBIT(chain)) return XUNMARK(chain);
-
- marker = dump_alloc(3 * sizeof(int));
- XSET(new,Lisp_Marker,OFFSET_IN_DUMP(marker));
- XMARKER(p)->chain = new;
- XMARK(XMARKER(p)->chain);
- buffer = XMARKER(p)->buffer;
- if (buffer != 0L)
- marker[0] = dump_one_object(XSET(t,Lisp_Buffer,buffer));
- else
- marker[0] = 0L;
- marker[1] = dump_one_object(chain);
- marker[2] = XMARKER(p)->bufpos;
- return new;
- }
-
- static Lisp_Object
- restore_Lisp_Marker(int *a)
- {
- int t,chain = a[1];
- if (XMARKBIT(chain)) return XUNMARK(chain);
- a[1] = t = Fmake_marker();
- XMARK(a[1]);
- XMARKER(t)->buffer = (a[0] == 0L ? 0L : XBUFFER(restore_one_object(a[0])));
- XMARKER(t)->chain = restore_one_object(chain);
- XMARKER(t)->bufpos = a[2];
- ++total_fixups;
- return t;
- }
-
- static Lisp_Object
- dump_Lisp_Intfwd(Lisp_Object p)
- {
- /* The problem with forwarded integers is that they can be assigned -1,
- for example, and with that assignment all bits are set, not just the
- bits for a regular lisp integer. So these values have no mark bit.
- Thus every reference to a forwarded object gets its own description. */
-
- int new,*a = dump_alloc(2 * sizeof(int));
- XSET(a[0],XTYPE(p),OFFSET_IN_DATA(p));
- a[1] = *(int *)XPNTR(p);
- return XSET(new,XTYPE(p),OFFSET_IN_DUMP(a));
- }
-
- static Lisp_Object
- restore_Lisp_Intfwd(int *a)
- {
- Lisp_Object t = restore_one_object(a[0]); /* a[0] is an offset into data segment */
- *(int *)XPNTR(t) = a[1];
- return t;
- }
-
- static Lisp_Object
- dump_one_object(Lisp_Object p)
- {
- int new,car,i,size;
-
- spin_chores();
-
- if (XTYPE(p) == Lisp_Int)
- return p;
-
- if (in_pure_space(p)) {
- XSET(new,XTYPE(p),OFFSET_IN_PURE(p));
-
- switch (XTYPE(p)) {
- case Lisp_String:
- return new;
- case Lisp_Cons:
- car = XCONS(p)->car;
- if (!XMARKBIT(car)) {
- XMARK(XCONS(p)->car);
- XCONS(p)->car = dump_one_object(car);
- XMARK(XCONS(p)->car);
- XCONS(p)->cdr = dump_one_object(XCONS(p)->cdr);
- }
- return new;
- case Lisp_Vector:
- size = XVECTOR(p)->size;
- if (!XMARKBIT(size)) {
- XMARK(XVECTOR(p)->size);
- for (i = 0; i<size; ++i)
- XVECTOR(p)->contents[i] = dump_one_object(XVECTOR(p)->contents[i]);
- }
- return new;
- default:
- panic("Unsupported lisp object found while dumping static objects");
- }
- }
-
- switch (XTYPE(p)) {
- case Lisp_Intfwd:
- case Lisp_Boolfwd:
- return dump_Lisp_Intfwd(p);
- case Lisp_Buffer_Objfwd:
- return p;
- case Lisp_String:
- return dump_Lisp_String(p);
- case Lisp_Symbol:
- return dump_Lisp_Symbol(p);
- case Lisp_Objfwd:
- return XSET(new,XTYPE(p),OFFSET_IN_DATA(p));
- case Lisp_Subr:
- return dump_Lisp_Subr(p);
- case Lisp_Cons:
- case Lisp_Buffer_Local_Value:
- return dump_Lisp_Cons(p);
- case Lisp_Vector:
- case Lisp_Window:
- return dump_Lisp_Vector(p);
- case Lisp_Buffer:
- return dump_Lisp_Buffer(p);
- case Lisp_Marker:
- return dump_Lisp_Marker(p);
- default:
- panic("Unsupported lisp object found while dumping static objects");
- }
- }
-
- static void
- dump_all_objects(void)
- {
- int i,p;
- struct buffer *b;
-
- for (i = 0; i<staticidx; ++i) {
- dumped_staticvec[i].object = dump_one_object(*staticvec[i]);
- dumped_staticvec[i].address = OFFSET_IN_DATA(staticvec[i]);
- }
-
- for (i = 0; i<nglobals_to_save; ++i)
- dumped_staticvec[staticidx+i].object =
- dump_one_object(globals_to_save[i].untagged ?
- XSET(p,globals_to_save[i].tag,*globals_to_save[i].address) :
- *globals_to_save[i].address);
-
- b = dump_alloc(sizeof(struct buffer));
- *b = buffer_local_flags;
- dumped_staticvec[staticidx + nglobals_to_save].address = OFFSET_IN_DUMP(b);
- }
-
- void
- map_out_data()
- {
- Handle h1,h2,h3;
- short refNum,err,errpt;
- char **dump_vector_handle;
- struct dumped_address_and_object **dumped_staticvec_handle;
- char **pure_handle;
-
- dump_vector_handle = NewHandle(DUMP_VECTOR_MAX);
- err = MemError(); if (err) { errpt = 0; goto error; }
- dumped_staticvec_handle = (struct dumped_address_and_object **)
- NewHandle(sizeof(struct dumped_address_and_object) *
- (staticidx+nglobals_to_save+1));
- err = MemError(); if (err) { errpt = 1; goto error; }
-
- /* loadup.el says we are dumping into a data file. */
- printf("Disregard that last message! Dumping into resource fork.\012");
- printf("Compacting...");
- fflush(stdout);
-
- HLock((Handle)dump_vector_handle);
- HLock((Handle)dumped_staticvec_handle);
- dump_vector = *dump_vector_handle;
- dumped_staticvec = *dumped_staticvec_handle;
- dump_free = 0;
- dump_all_objects();
-
- printf("done.\012Writing out new resources...");
- fflush(stdout);
-
- HUnlock(dump_vector_handle);
- HUnlock((Handle)dumped_staticvec_handle);
- pure_handle = RecoverHandle(pure);
- HUnlock(pure_handle);
- SetHandleSize(dump_vector_handle,dump_free);
-
- /* Remove the old resources. */
- SetResLoad(0);
- h1 = GetResource('Dump',STATICVEC_DUMP);
- h2 = GetResource('Dump',IMPURE_DUMP);
- h3 = GetResource('Dump',PURE_DUMP);
- SetResLoad(1);
- if (h1) RmveResource(h1), DisposHandle(h1);
- if (h2) RmveResource(h2), DisposHandle(h2);
- if (h3) RmveResource(h3), DisposHandle(h3);
-
- /* Add in the new ones. */
- AddResource((Handle)dumped_staticvec_handle,'Dump',STATICVEC_DUMP,0L);
- err = ResError(); if (err) { errpt = 2; goto error; }
- AddResource(dump_vector_handle,'Dump',IMPURE_DUMP,0L);
- err = ResError(); if (err) { errpt = 3; goto error; }
- AddResource(pure_handle,'Dump',PURE_DUMP,0L);
- err = ResError(); if (err) { errpt = 4; goto error; }
-
- /* Force out the changes. */
- refNum = HomeResFile((Handle)dumped_staticvec_handle);
- err = ResError(); if (err) { errpt = 5; goto error; }
- UpdateResFile(refNum);
- err = ResError(); if (err) { errpt = 6; goto error; }
-
- printf("done.");
- fflush(stdout);
-
- /* We quit here. We can't return to the interpreter with
- all the changes in the data. */
-
- ExitToShell();
-
- error:
- printf("Error %d at point %d\012",err,errpt);
- panic("Not enough memory or disk space to create new image -- "
- "restart with a larger partition or free some disk space");
- }
-
- static Lisp_Object
- restore_one_object(Lisp_Object p)
- {
- int i,size,car,offset,*a,type;
- register Lisp_Object t;
-
- spin_chores();
-
- type = XTYPE(p);
- if (type == Lisp_Int) return p;
- offset = OFFSET(p);
-
- switch (SEGMENT(p)) {
- case NO_SEGMENT:
- return p;
- case DATA_SEGMENT:
- ++total_fixups;
- return XSET(t,type,(int)((char *)&pure + offset));
- case PURE_SEGMENT:
- ++total_fixups;
- XSET(t,type,(int)((char *)pure + offset));
- switch (type) {
- case Lisp_String:
- return t;
- case Lisp_Vector:
- size = XVECTOR(t)->size;
- if (XMARKBIT(size)) {
- XUNMARK(XVECTOR(t)->size);
- size = XVECTOR(t)->size;
- for (i = 0; i<size; ++i)
- XVECTOR(t)->contents[i] = restore_one_object(XVECTOR(t)->contents[i]);
- }
- return t;
- case Lisp_Cons:
- car = XCONS(t)->car;
- if (XMARKBIT(XCONS(t)->car)) {
- XUNMARK(XCONS(t)->car);
- XCONS(t)->car = restore_one_object(XCONS(t)->car);
- XCONS(t)->cdr = restore_one_object(XCONS(t)->cdr);
- }
- return t;
- default:
- panic("Unsupported lisp object found in restore_one_object");
- }
- case DUMP_SEGMENT:
- ++total_fixups;
- a = (int *)(dump_vector + offset);
-
- switch (type) {
- case Lisp_Intfwd:
- case Lisp_Boolfwd:
- return restore_Lisp_Intfwd(a);
- case Lisp_String:
- return restore_Lisp_String(a);
- case Lisp_Subr:
- return restore_Lisp_Subr(a);
- case Lisp_Cons:
- case Lisp_Buffer_Local_Value:
- return restore_Lisp_Cons(a,type);
- case Lisp_Vector:
- case Lisp_Window:
- return restore_Lisp_Vector(a,type);
- case Lisp_Symbol:
- return restore_Lisp_Symbol(a);
- case Lisp_Buffer:
- return restore_Lisp_Buffer(a);
- case Lisp_Marker:
- return restore_Lisp_Marker(a);
- default:
- panic("Unsupported lisp object found while restoring dumped data");
- }
- }
- }
-
- static void
- load_and_fixup_dump()
- {
- int i,address,offset;
- struct buffer *b;
-
- for (i = 0; i<staticidx; ++i) {
- address = OFFSET(dumped_staticvec[i].address);
- staticvec[i] = (Lisp_Object *)((char *)&pure + address);
- *staticvec[i] = restore_one_object(dumped_staticvec[i].object);
- ++total_fixups;
- }
-
- for (i = 0; i<nglobals_to_save; ++i) {
- *globals_to_save[i].address =
- restore_one_object(dumped_staticvec[staticidx+i].object);
- if (globals_to_save[i].untagged)
- *globals_to_save[i].address =
- globals_to_save[i].tag == Lisp_Int ?
- XINT(*globals_to_save[i].address) :
- XUINT(*globals_to_save[i].address);
- ++total_fixups;
- }
-
- offset = OFFSET(dumped_staticvec[staticidx + nglobals_to_save].address);
- b = (struct buffer *)(dump_vector + offset);
- buffer_local_flags = *b;
- ++total_fixups;
- }
-
- void
- reverse_unexec(void)
- {
- Handle h1,h2,h3;
-
- h1 = GetResource('Dump',STATICVEC_DUMP);
- h2 = GetResource('Dump',IMPURE_DUMP);
- h3 = GetResource('Dump',PURE_DUMP);
- if (h1 == 0L || h2 == 0L || h3 == 0L) panic("Can't find dumped data.\012"
- "Rerun Emacs holding down the option key at startup.");
-
- MoveHHi(h1); HLock(h1); HNoPurge(h1);
- MoveHHi(h2); HLock(h2); HNoPurge(h2);
- MoveHHi(h3); HLock(h3); HNoPurge(h3);
-
- dumped_staticvec = (struct dumped_address_and_object *)*h1;
- staticidx = GetHandleSize(h1) / sizeof(struct dumped_address_and_object)
- - nglobals_to_save - 1;
- dump_vector = StripAddress(*h2);
- dump_free = GetHandleSize(h2);
- pure = StripAddress(*h3);
-
- load_and_fixup_dump();
-
- HUnlock(h1); HPurge(h1); ReleaseResource(h1);
- HUnlock(h2); HPurge(h2); ReleaseResource(h2);
- }
-